package com.wang.tool.dagre.node;


import com.wang.tool.dagre.DagreContext;

import java.util.Collection;

/**
 * @Description 图流程节点
 * @Author shaopeng
 * @Date 2021/7/21
 * @Version 1.0
 */
public interface DagreNode<T> {

    /**
     * 预检查空对象锚定对象
     */
    Object NULL_VAL = new Object();

    /**
     * id
     *
     * @return 非空
     */
    String getId();

    /**
     * 依赖的节点id
     *
     * @return 为空代表无依赖
     */
    Collection<String> getDependIds();

    /**
     * 是否是同步节点
     * 同步节点不启用线程池,纯内存计算的节点使用线程池反而会慢/耗资源
     * 注意:谨慎设置,同步节点是顺序执行的,不当设置会使得节点间阻塞
     *
     * @return 是否是同步节点
     */
    boolean isSync();

    /**
     * 节点预验证
     * 注意:抛出异常,执行中断
     * 当节点在图流程中可以简单判断节点是否需要执行,如果无需执行则可以直接框架层过滤，省的无效调度
     * 同步判断,不当使用会使得节点间阻塞
     * @param context 非空
     * @return 返回非空，则直接将结果当做结果处理,不对execute进行调度执行
     * @see AbsDagreNode#buildPreResult NULL_VAL 如果想过滤执行 & 返回null 则返回此值
     * @throws Throwable 抛出异常,流程中断
     */
    Object preCheck(DagreContext<T> context) throws Throwable;

    /**
     * 干活
     *
     * @param context 非空
     * @return 节点执行结果
     * @throws Throwable 抛出异常,流程中断
     */
    Object execute(DagreContext<T> context) throws Throwable;


    /**
     * 慢调用阈值
     * 异常不影响主业务执行
     *
     * @param context 非空
     * @return 返回空代表无限制
     */
    default Integer getSlowTime(DagreContext<T> context) {
        //同步节点在触发线程执行,可能会阻塞后续节点
        return isSync() ? 5 : null;
    }
}
